package com.easychat.service.impl;

import com.easychat.common.LeaseException;
import com.easychat.common.PageResult;
import com.easychat.entity.AppUpdate;
import com.easychat.entity.query.AppUpdateQuery;
import com.easychat.entity.config.AppConfig;
import com.easychat.entity.constants.Constants;
import com.easychat.enums.AppUpdateFileTypeEnum;
import com.easychat.enums.AppUpdateStatusEnum;
import com.easychat.enums.ExceptionCodeEnum;
import com.easychat.mappers.AppUpdateDao;
import com.easychat.service.AppUpdateService;
import com.easychat.utils.StringTools;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * (AppUpdate)表服务实现类
 *
 * @author makejava
 * @since 2024-10-14 16:39:36
 */
@Service("appUpdateService")
public class AppUpdateServiceImpl implements AppUpdateService {
    @Resource
    private AppUpdateDao appUpdateDao;
    @Resource
    private AppConfig appConfig;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public AppUpdate queryById(Integer id) {
        return this.appUpdateDao.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param appUpdate 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<AppUpdate> queryByPage(AppUpdate appUpdate, PageRequest pageRequest) {
        long total = this.appUpdateDao.count(appUpdate);
        return new PageImpl<>(this.appUpdateDao.queryAllByLimit(appUpdate, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param appUpdate 实例对象
     * @return 实例对象
     */
    @Override
    public AppUpdate insert(AppUpdate appUpdate) {
        this.appUpdateDao.insert(appUpdate);
        return appUpdate;
    }

    /**
     * 修改数据
     *
     * @param appUpdate 实例对象
     * @return 实例对象
     */
    @Override
    public AppUpdate update(AppUpdate appUpdate) {
        this.appUpdateDao.update(appUpdate);
        return this.queryById(appUpdate.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        AppUpdate dbInfo = appUpdateDao.queryById(id);
        if(!AppUpdateStatusEnum.INIT.getStatus().equals(dbInfo.getStatus())){
            throw new LeaseException(ExceptionCodeEnum.ERROR_REQUEST);
        }
        return this.appUpdateDao.deleteById(id) > 0;
    }

    @Override
    public PageResult queryListByPage(AppUpdateQuery query) {
        PageHelper.startPage(query.getPageNum(),query.getPageSize());
        PageHelper.orderBy(query.getOrderBy());
        AppUpdate appUpdate = new AppUpdate();
        BeanUtils.copyProperties(query,appUpdate);
        List<AppUpdate> appUpdateList = appUpdateDao.queryByPage(appUpdate);
        long count = appUpdateDao.count(appUpdate);
        return new PageResult(count,appUpdateList);
    }

    @Override
    public void saveUpdate(AppUpdate appUpdate, MultipartFile file) throws IOException {
        AppUpdateFileTypeEnum fileTypeEnum = AppUpdateFileTypeEnum.getByType(appUpdate.getFileType());
        if(fileTypeEnum == null){
            throw new LeaseException(ExceptionCodeEnum.ERROR_REQUEST);
        }

        if(appUpdate.getId()!=null){
            AppUpdate dbInfo = appUpdateDao.queryById(appUpdate.getId());
            if(!AppUpdateStatusEnum.INIT.getStatus().equals(dbInfo.getStatus())){
                throw new LeaseException(ExceptionCodeEnum.ERROR_REQUEST);
            }

        }
        PageHelper.startPage(0,1);
        PageHelper.orderBy("id desc");
        List<AppUpdate> appUpdateList = appUpdateDao.queryByPage(new AppUpdate());
        if(!appUpdateList.isEmpty()){
            AppUpdate lastest = appUpdateList.get(0);
            Long dbVersion = Long.parseLong(lastest.getVersion().replace(".", ""));
            Long currentVersion = Long.parseLong(appUpdate.getVersion().replace(".",""));
            if(appUpdate.getId() == null && currentVersion <= dbVersion){
                throw new LeaseException("当前版本必须大于历史版本");
            }
            if(appUpdate.getId() != null && currentVersion <= dbVersion && !appUpdate.getVersion().equals(lastest.getVersion())){
                throw new LeaseException("当前版本必须大于历史版本");
            }

        }
        if(appUpdate.getId() == null){
            appUpdate.setCreateTime(new Date());
            appUpdate.setStatus(AppUpdateStatusEnum.INIT.getStatus());
            appUpdateDao.insert(appUpdate);
        }else {
            appUpdate.setStatus(null);
            appUpdate.setGrayscaleUid(null);
            appUpdateDao.update(appUpdate);
        }
        if(file != null){
            File folder = new File(appConfig.getProjectFolder() + Constants.APP_UPDATE_FOLDER);
            if(!folder.exists()){
                folder.mkdirs();
            }
            file.transferTo(new File(folder.getPath() + "/" + appUpdate.getId() + Constants.APP_EXE_SUFFIX));
        }


    }

    @Override
    public void postUpdate(Integer id, Integer status, String grayscaleUid) {
        AppUpdateStatusEnum fileTypeEnum = AppUpdateStatusEnum.getByStatus(status);
        if(null == fileTypeEnum){
            throw new LeaseException(ExceptionCodeEnum.ERROR_REQUEST);
        }
        if(fileTypeEnum == AppUpdateStatusEnum.GRAYSCALE && StringTools.isEmpty(grayscaleUid)){
            throw new LeaseException("灰度发布必须有指定用户");
        }
        if(AppUpdateStatusEnum.GRAYSCALE != fileTypeEnum ){
            grayscaleUid = "";
        }
        AppUpdate appUpdate = new AppUpdate();
        appUpdate.setId(id);
        appUpdate.setStatus(status);
        appUpdate.setGrayscaleUid(grayscaleUid);
        appUpdateDao.update(appUpdate);

    }

    @Override
    public AppUpdate getLatestUpdate(String appVersion, String uid) {

        return appUpdateDao.selectLatestUpdate(appVersion,uid);
    }
}
